1. Field
The field relates to security in a computing environment.
2. Related Art
A system for running code may offer safety properties, such as memory safety. The system may include a set of trusted libraries that untrusted third-party code may use. However, these libraries may include some code that could violate the safety properties of the system if called with the wrong parameters. An important goal of constructing a safe environment for running code is to prevent user code from violating the system's safety properties, despite the presence of unsafe code in the libraries.
A system may run code with safety properties (“managed code”), as well as code written in a different language without safety properties (“native code”). Managed code will not violate safety properties unless it calls native code with parameters that trigger unsafe behavior.
An important goal of a system that offers safety properties is to ensure that only safe methods are visible to user code. As a result, user code may run in the system without violating the safety properties of the system.
One example of how to approach the problem of constructing a system for running code that offers safety properties is JAVA technology. JAVA technology includes a language and a virtual machine (VM) that help run code that offers safety properties.
The JAVA language's access modifiers are typically used to prevent unsafe methods from being exposed to user code. JAVA technology includes the access modifiers “public”, “protected”, “package-private” (this label is the default, and is the label used unless another access modifier is used), and “private”. The access modifier with which a method is associated determines the places in a set of JAVA code from where a method is visible and may be accessed.
JAVA technology is able to protect code to some extent by ensuring that native code that is unsafe is either marked private or package-private, thus restricting the code's visibility. This approach has several shortcomings. First, user code in the JAVA language may use reflection to bypass access modifiers and call unsafe methods. In reflection, a JAVA program may observe and modify its own operation at runtime, by using the library java.lang.reflect. Unless this capability is carefully regulated, reflection allows unsafe behavior.
Second, user code in the JAVA language may define its own native methods that violate the system's safety properties (i.e., are unsafe). Once again, unless this capability is controlled, this capability may allow unsafe behavior. The JAVA language provides a customizable SecurityManager that may help address unsafe behavior by native methods defined in user code. However, to manage the unsafe behavior, SecurityManager may also prevent the use of other desirable features. For example, use of SecurityManager may prevent unsafe behavior by blocking the defining of custom class loaders.
Another issue in the JAVA language as it presently operates is that there is no guiding documentation about which private or package-private methods are unsafe. While the private and package-private methods may be inaccessible, the lack of safety information for such methods may make it difficult for auditing tools to determine which methods pose a safety risk and which do not.
Also, as the JAVA language's system libraries are currently constructed, some methods in the JAVA language's system libraries have a public access modifier but are not safe to expose to user code. For example, the putObject method in the sun.misc.Unsafe class is a public instance method that may violate memory safety. This method is not actually visible to user code because an instance of the sun.misc.Unsafe class may only be constructed by system code, and system code never makes an instance available to user code. Thus, the public access modifier on the method may be misleading and does not accurately categorize methods as safe or unsafe.
The .NET Code Access Security faces similar issues with defining potentially unsafe methods for languages such as Visual C#. .NET and Visual C# favor runtime components that check whether code and callers of that code have permissions to perform particular actions. The runtime components represent an approach that helps manage potentially unsafe use of methods. For example, one runtime component is an assertion capability. However, such an assertion capability offers limited security and may not be able to handle many threats.